//
//  DataCache.m
//  niuPei
//
//  Created by hh on 15/6/6.
//  Copyright (c) 2015年 hh. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "DataCache.h"
#import "ViewController.h"
#import "LoginViewController.h"

@implementation DataCache

static DataCache *data;
static NSOperationQueue *queue;

- (instancetype)init
{
    self = [super init];
    
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    
    NSString *domain = @"接口域名";
    _baseURL = domain;
    
    _hasLogin = [[def valueForKey:@"hasLogin"] boolValue] ? : NO;
    _token = [def valueForKey:@"token"]?:@"";
    NSData *loginData = [def valueForKey:@"loginInfo"];
    if (loginData) {
        _loginInfo = [NSKeyedUnarchiver unarchiveObjectWithData:loginData];
    }
    
    return self;
}

- (void)saveState
{
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    [def setValue:@(_hasLogin) forKey:@"hasLogin"];
    if (_token) {
        [def setValue:_token forKey:@"token"];
    }else{
        [def removeObjectForKey:@"token"];
    }
    if (_loginInfo) {
        NSData *loginData = [NSKeyedArchiver archivedDataWithRootObject:_loginInfo];
        [def setValue:loginData forKey:@"loginInfo"];
    }else{
        [def removeObjectForKey:@"loginInfo"];
    }
}

- (void)dealloc
{
    [self saveState];
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    [def synchronize];
}

+ (instancetype)sharedData
{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        data = [[self alloc] init];
    });
    return data;
}

#pragma mark - 登录逻辑
+ (void)checkIfLogin:(UIViewController *)con
{
    if (!data) {
        [DataCache sharedData];
    }
    if (!data.hasLogin && data.token.length == 0) {
        NSLog(@"not login && token=%@",data.token);
        UIViewController *con = [Helper getCurrentViewController];
        [MBProgressHUD hideAllHUDsForView:con.view animated:NO];
        if ([con isKindOfClass:[LoginViewController class]]) {
            return;
        }
        LoginViewController *loginCon = [[LoginViewController alloc] init];
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:loginCon];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [con presentViewController:nav animated:YES completion:nil];
        });
    }
}

#pragma mark - 接口实现 - 登录
+ (void)loginWithName:(NSString *)name password:(NSString *)passwd complete:(void (^)(BOOL))handle
{
    NSDictionary *param = @{
                            @"客户名称":name?:@"",
                            @"登陆密码":passwd?:@"",
                           };
    
    [self getDataWithParam:param method:@"GET" bodyData:nil urlString:@"/api/login(根据真实地址修改)" dataClass:[LoginResultData class] complete:^(LoginResultData *d){
        // 注意，加此句为提示该方法耗时
        NSLog(@"%s",__FUNCTION__);
        
        if (d.errcode.intValue == 0 && d.record) {
            data.hasLogin = YES;
            data.token = d.record.token;
            data.loginInfo = d.record;
            data.loginInfo.登陆密码 = passwd;
            [data saveState];
            if (handle) {
                handle(YES);
            }
        }else{
            data.hasLogin = NO;
            
            UIViewController *con = [Helper getCurrentViewController];
            if (![con isKindOfClass:[LoginViewController class]]) {
                data.token = nil;
                handle(NO);
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self checkIfLogin:con];
                });
            }else{
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (name.length > 0 && passwd) {
                        SHOW_ALERT((d.errmsg.length>4?d.errmsg:@"用户名/密码错误！"));
                    }
                    handle(NO);
                });
            }
        }
    }];
}

//示范使用
//#pragma mark - 自助算价
//+ (void)getPrice:(NSString *)string complete:(void (^)(ValueData *d))handle
//{
//    NSString *str = [NSString stringWithFormat:@"%@-%@",data.loginInfo.客户代码, string];
//    NSDictionary *param = @{
//                            @"客户代码":data.loginInfo.客户代码?:@"",
//                            @"登陆密码":data.loginInfo.登陆密码?:@"",
//                            @"算价要求":str?:@""
//                            };
//    
//    [self getDataWithParam:param method:@"GET" bodyData:nil urlString:@"/api/Sys" dataClass:[ValueData class] complete:handle];
//}

#pragma mark - 根据URL判断图片是否存在
+ (void)imgURLExists:(NSString *)urlString complete:(void (^)(BOOL))handle
{
    NSURL *url = [NSURL URLWithString:urlString];
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    req.HTTPMethod = @"HEAD";
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
        dispatch_async(dispatch_get_main_queue(), ^{
            if (res.statusCode == 200) {
                handle(YES);
            }else{
                handle(NO);
            }
        });
    }];
    [task resume];
}


#pragma mark - 网络获取数据

/*
 * 最底层方法
 */
+ (void)getDataWithParam:(NSDictionary*)param method:(NSString *)method bodyData:(NSString *)body urlString:(NSString*)urlString dataClass:(Class)DataClass complete:(void (^)(id data))handle
{
    if (!data) {
        [self sharedData];
    }
    if (!data.baseURL || data.baseURL.length < 4) {
        dispatch_async(dispatch_get_main_queue(), ^(){
            UIViewController *con = [Helper getCurrentViewController];
            [MBProgressHUD hideAllHUDsForView:con.view animated:YES];
        });
        NSLog(@"getData returned.");
        return;
    }
    
    if (![urlString hasPrefix:@"/"]) {
        urlString = [@"/" stringByAppendingString:urlString];
    }
    NSString *urlString_ = [NSString stringWithFormat:@"%@%@",data.baseURL,urlString];
    // 拼接GET参数
    NSArray *arr = [param.allKeys mapArrayWithBlock:^NSString *(NSString *key) {
        return [NSString stringWithFormat:@"%@=%@",key, param[key]];
    }];
    NSString *queryString = [arr componentsJoinedByString:@"&"];
    if ([urlString containsString:@"login"]) {
        queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&token=%@", data.token]];
    }
    NSString *url_ = urlString_;
    if (queryString.length > 0) {
        url_ = [url_ stringByAppendingFormat:@"?%@",queryString];
    }
    NSURL *url = [NSURL URLWithString:[url_ stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
    // 增加http首部，标志自己是iOS客户端（根据需要使用，可以不用）
    [request setValue:@"XXX's iOS clients" forHTTPHeaderField:@"User-Agent"];
    request.HTTPMethod = method?:@"GET";
    if (body) {
        request.HTTPBody = [body dataUsingEncoding:NSUTF8StringEncoding];
        [request setValue:[NSString stringWithFormat:@"%lu",request.HTTPBody.length] forHTTPHeaderField:@"Content-Length"];
    }
    
    if (!queue) {
        queue = [NSOperationQueue new];
    }
    NSLog(@"%@",request.URL.absoluteString.stringByRemovingPercentEncoding);
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable resData, NSURLResponse * _Nullable response, NSError * _Nullable connectionError) {
        
        if (connectionError) {
            NSString *tips = @"亲，网络异常，请检查网络配置";
            if (connectionError.code == NSURLErrorTimedOut) {
                 tips = @"亲，之前的请求超时。";
            }
            dispatch_async(dispatch_get_main_queue(), ^(){
                UIViewController *con = [Helper getCurrentViewController];
                [MBProgressHUD hideAllHUDsForView:con.view animated:YES];
                [Helper showTips:tips forTime:0.8 inView:[Helper getCurrentViewController].view yOffset:80];
                    BaseData *base = [BaseData new];
                    base.errcode = @"40000";
                    base.errmsg = tips;
                    handle(base);
            });
            return;
        }
        
        NSString *s = [[NSString alloc] initWithBytes:resData.bytes length:resData.length encoding:NSUTF8StringEncoding];
        
        NSLog(@"原始数据：%@",s);
        
        //系统自带JSON解析
        NSError *error;
        id d = [NSJSONSerialization JSONObjectWithData:resData options:NSJSONReadingAllowFragments error:&error];
//        NSLog(@"%@",d);
        int errcode = [[d objectForKey:@"errcode"] intValue];
        NSString *errmsg = [d objectForKey:@"errmsg"];
        if (errcode == 1) {
            data.hasLogin = NO;
            [queue cancelAllOperations];
            
            [self loginWithName:data.loginInfo.客户代码 password:data.loginInfo.登陆密码 complete:^(BOOL success){
                if (success) {
                    // 登录成功则重新之前的调用
                    [self getDataWithParam:param method:method bodyData:body urlString:urlString dataClass:DataClass complete:handle];
                }else{
                    dispatch_async(dispatch_get_main_queue(), ^(){
                        UIViewController *con = [Helper getCurrentViewController];
                        [MBProgressHUD hideAllHUDsForView:con.view animated:YES];
                        BaseData *base = [[BaseData alloc] initWithDictionary:d];
                        handle(base);
                    });
                }
            }];
            return;
        }else if (errcode != 0) {
            switch (errcode) {
                // 这些异常需要统一弹窗警告
                // 错误代码项目会设计好并给出
                case 70040:
                {
                    dispatch_async(dispatch_get_main_queue(), ^(){
                        // 自己弹窗处理
                    });
                }
                    break;
                    
                default:
                    dispatch_async(dispatch_get_main_queue(), ^(){
                        // 默认处理
                    });
                    break;
            }
        }
        if (!error && d) {
            dispatch_async(dispatch_get_main_queue(), ^(){
                // 当错误发生时，传送错误信息回当前控制器
                if (errcode != 0) {
                    handle([[BaseData alloc] initWithDictionary:d]);
                    return;
                }
                if (DataClass == NSDictionary.class) {
                    handle(d);
                    return;
                }
                if ([d isKindOfClass:[NSArray class]]) {
                    NSMutableArray *arr = [NSMutableArray array];
                    for (NSDictionary *dict in d) {
                        id res = [[DataClass alloc] initWithDictionary:dict];
                        [arr addObject:res];
                    }
                    handle(arr);
                }else if([d isKindOfClass:[NSDictionary class]]){
                    id res = [[DataClass alloc] initWithDictionary:d];
                    handle(res);
                }else{
                    NSLog(@"json data is not NSArray or NSDictionary");
                    handle(d);
                }
            });
        }else{
            NSLog(@"get json succeed, but fail to analyse");
            dispatch_async(dispatch_get_main_queue(), ^(){
                UIViewController *con = [Helper getCurrentViewController];
                [MBProgressHUD hideAllHUDsForView:con.view animated:YES];
//                SHOW_ALERT2(@"服务器没有返回任何jsons数据!");
                BaseData *base = [BaseData new];
                base.errcode = @"40000";
                base.errmsg = /*[[NSString alloc] initWithData:resData encoding:NSUTF8StringEncoding];/*/@"亲，访问网络出了问题，请稍后重试！";
                handle(base);
                SHOW_TIPS(base.errmsg, 0);
            });
            return;
        }
    }];
    
    [task resume];
}

@end
